#include"../server.hpp"
#include<iostream>
#include<vector>
#include<algorithm>
#include<cassert>
#include<fstream>
#include<unordered_map>
#include<string>
#include<cstdio>
#include<cctype>
#include <sys/stat.h>
#include<regex>

  std::unordered_map<int,std::string> _statu_mag={
    {100, "Continue"},
{101, "Switching Protocol"},
 {102, "Processing"},
 {103, "Early Hints"},
 {200, "OK"},
 {201, "Created"},
 {202, "Accepted"},
 {203, "Non-Authoritative Information"},
 {204, "No Content"},
 {205, "Reset Content"},
 {206, "Partial Content"},
 {207, "Multi-Status"},
 {208, "Already Reported"},
 {226, "IM Used"},
 {300, "Multiple Choice"},
 {301, "Moved Permanently"},
 {302, "Found"},
 {303, "See Other"},
 {304, "Not Modified"},
 {305, "Use Proxy"},
 {306, "unused"},
 {307, "Temporary Redirect"},
 {308, "Permanent Redirect"},
 {400, "Bad Request"},
 {401, "Unauthorized"},
 {402, "Payment Required"},
 {403, "Forbidden"},
 {404, "Not Found"},
 {405, "Method Not Allowed"},
 {406, "Not Acceptable"},
 {407, "Proxy Authentication Required"},
 {408, "Request Timeout"},
 {409, "Conflict"},
 {410, "Gone"},
 {411, "Length Required"},
 {412, "Precondition Failed"},
 {413, "Payload Too Large"},
 {414, "URI Too Long"},
 {415, "Unsupported Media Type"},
 {416, "Range Not Satisfiable"},
 {417, "Expectation Failed"},
 {418, "I'm a teapot"},
 {421, "Misdirected Request"},
 {422, "Unprocessable Entity"},
 {423, "Locked"},
 {424, "Failed Dependency"},
 {425, "Too Early"},
 {426, "Upgrade Required"},
 {428, "Precondition Required"},
 {429, "Too Many Requests"},
 {431, "Request Header Fields Too Large"},
 {451, "Unavailable For Legal Reasons"},
 {501, "Not Implemented"},
 {502, "Bad Gateway"},
 {503, "Service Unavailable"},
 {504, "Gateway Timeout"},
 {505, "HTTP Version Not Supported"},
 {506, "Variant Also Negotiates"},
 {507, "Insufficient Storage"},
 {508, "Loop Detected"},
 {510, "Not Extended"},
 {511, "Network Authentication Required"}
  };

std::unordered_map<std::string, std::string> _mime_msg = {
 {".aac", "audio/aac"},
 {".abw", "application/x-abiword"},
 {".arc", "application/x-freearc"},
 {".avi", "video/x-msvideo"},
 {".azw", "application/vnd.amazon.ebook"},
 {".bin", "application/octet-stream"},
 {".bmp", "image/bmp"},
 {".bz", "application/x-bzip"},
 {".bz2", "application/x-bzip2"},
 {".csh", "application/x-csh"},
 {".css", "text/css"},
 {".csv", "text/csv"},
 {".doc", "application/msword"},
 {".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
 {".eot", "application/vnd.ms-fontobject"},
 {".epub", "application/epub+zip"},
 {".gif", "image/gif"},
 {".htm", "text/html"},
 {".html", "text/html"},
 {".ico", "image/vnd.microsoft.icon"},
 {".ics", "text/calendar"},
 {".jar", "application/java-archive"},
 {".jpeg", "image/jpeg"},
 {".jpg", "image/jpeg"},
 {".js", "text/javascript"},
 {".json", "application/json"},
 {".jsonld", "application/ld+json"},
 {".mid", "audio/midi"},
 {".midi", "audio/x-midi"},
 {".mjs", "text/javascript"},
 {".mp3", "audio/mpeg"},
 {".mpeg", "video/mpeg"},
 {".mpkg", "application/vnd.apple.installer+xml"},
 {".odp", "application/vnd.oasis.opendocument.presentation"},
{".ods", "application/vnd.oasis.opendocument.spreadsheet"},
 {".odt", "application/vnd.oasis.opendocument.text"},
 {".oga", "audio/ogg"},
 {".ogv", "video/ogg"},
 {".ogx", "application/ogg"},
 {".otf", "font/otf"},
 {".png", "image/png"},
 {".pdf", "application/pdf"},
 {".ppt", "application/vnd.ms-powerpoint"},
 {".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"},
 {".rar", "application/x-rar-compressed"},
 {".rtf", "application/rtf"},
 {".sh", "application/x-sh"},
 {".svg", "image/svg+xml"},
 {".swf", "application/x-shockwave-flash"},
 {".tar", "application/x-tar"},
 {".tif", "image/tiff"},
 {".tiff", "image/tiff"},
 {".ttf", "font/ttf"},
 {".txt", "text/plain"},
 {".vsd", "application/vnd.visio"},
 {".wav", "audio/wav"},
 {".weba", "audio/webm"},
 {".webm", "video/webm"},
 {".webp", "image/webp"},
 {".woff", "font/woff"},
 {".woff2", "font/woff2"},
 {".xhtml", "application/xhtml+xml"},
 {".xls", "application/vnd.ms-excel"},
 {".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
 {".xml", "application/xml"},
 {".xul", "application/vnd.mozilla.xul+xml"},
 {".zip", "application/zip"},
 {".3gp", "video/3gpp"},
 {".3g2", "video/3gpp2"},
 {".7z", "application/x-7z-compressed"}
};
class Util{
public:
static size_t Split(const std::string& str, const std::string& delim, std::vector<std::string>* result) {
// str是要分割的字符串，delim是分隔符，result是存储分割结果的容器
  
  size_t offset = 0;//偏移量-当前指向位置下标
  while(offset < str.size()) {
    size_t pos = str.find(delim, offset);//查找分隔符位置
    
    if (pos == std::string::npos) {//如果没找到
     if(pos==str.size())break;//如果分隔符在字符串末尾则不添加
     
        result->push_back(str.substr(offset));//将剩余部分添加到结果中
      return result->size(); // 返回分割后的部分数量
    }
    if(pos == offset) {//如果分隔符在开头
      offset += delim.size(); // 跳过分隔符
      continue; // 继续查找下一个分隔符
    }
    result->push_back(str.substr(offset, pos - offset));//将分隔符前的部分添加到结果中
    offset = pos + delim.size();//更新偏移量
  }
  return result->size(); // 返回分割后的部分数量

}


static bool ReadFile(const std::string& filename, std::string* content) {
    assert(content != nullptr);
    std::ifstream ifs(filename,std::ios::binary);// 打开文件,以二进制方式读取
    if(ifs.is_open()==false) {
        printf("open file %s failed\n", filename.c_str());
        return false;
    }

    ifs.seekg(0, std::ios::end); // 移动到文件末尾
    size_t size = ifs.tellg(); // 获取文件大小
    ifs.seekg(0, std::ios::beg); // 移动到文件开头
    content->resize(size); // 调整内容大小
    ifs.read(&(*content)[0], size); // 读取文件内容到字符串
    if(ifs.good() == false) {
        printf("read file %s failed\n", filename.c_str());
        return false;
    }

    ifs.close(); // 关闭文件
    return true;
  }

  static bool WriteFile(const std::string& filename, const std::string& content) {
    std::ofstream ofs(filename,std::ios::binary|std::ios::trunc); // 打开文件,以二进制方式写入,清空文件内容
    if(!ofs.is_open()) {
        printf("open file %s failed\n", filename.c_str());
        return false; 
    }

    ofs.write(content.data(), content.size()); // 写入内容到文件
  if(ofs.good() == false) {
        printf("write file %s failed\n", filename.c_str());
        return false;
    }

    ofs.close(); // 关闭文件
    return true;
  
  }
  
static std::string StatuDesc(int statu)
{
    auto it = _statu_mag.find(statu);
  if(it != _statu_mag.end()) {
    return it->second;
  } else {
    return "Unknown Status";
}
}
  static std::string UrlEncode(const std::string &url,bool convert_sapce_to_plus = false) {
    std::string encoded;
    for (char c : url) {
        if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~'||isalnum(c)) {
            encoded += c; // 保留字母、数字和某些特殊字符
            continue;
        } else if (c == ' ' && convert_sapce_to_plus) {
            encoded += '+'; // 将空格转换为加号
            continue;
        } else {
            char buf[4]={0};
            snprintf(buf, sizeof(buf), "%%%02X", static_cast<unsigned char>(c)); //%%%02X格式化字符为十六进制--%%为转义字符将%输出为%，%02X将字符转换为两位十六进制数,0为前补零，2为两位
            encoded += buf;
        }
    }
    return encoded;
  }

static char Decodechar(char c){
  if(c >= '0' && c <= '9') {
    return c - '0'; // 数字字符转换为对应的整数值
  } else if(c >= 'A' && c <= 'F') {
    return c - 'A' + 10; // 大写字母转换为对应的整数值
  } else if(c >= 'a' && c <= 'f') {
    return c - 'a' + 10; // 小写字母转换为对应的整数值
  }
   printf("decode char %c failed\n", c);
  return -1;
}

  static std::string UrlDecode(const std::string &url,bool convert_sapce_to_plus = false) {
    std::string decoded;
    for (size_t i = 0; i < url.size(); ++i) {
      if(convert_sapce_to_plus && url[i] == '+') {
            decoded += ' '; // 将加号转换为空格
            continue;
        }
        if (url[i] == '%'&&i+2<url.size()) {
           decoded+=Decodechar(url[i + 1]) * 16 + Decodechar(url[i + 2]); // 将%后面的两位十六进制数转换为字符
            i += 2; // 跳过已处理的两个字符
        }
    }
    return decoded;
  }
//判断path是否是一个目录
  static bool IsDirectory(const std::string& path) {
    struct stat statbuf;
    int ret=stat(path.c_str(), &statbuf);
    if(ret<0)return false; // 如果stat失败，返回false
    return S_ISDIR(statbuf.st_mode); // 检查路径是否为目录
  }
//判断path是否是一个常规文件
  static bool IsFile(const std::string& path) {
    struct stat statbuf;
    int ret=stat(path.c_str(), &statbuf);
    if(ret<0)return false; // 如果stat失败，返回false
    return S_ISREG(statbuf.st_mode); // 检查路径是否为常规文件
  }


  static bool ValidPath(const std::string& path) {
    if(path.empty()) return false; // 路径不能为空
    std::vector<std::string> parts;
    Split(path, "/", &parts); // 分割路径
    int level = 0; // 路径层级
    for(const auto& part : parts) {
      if(part=="..") {
       level--; // 上一级目录
        if(level < 0) return false; // 如果层级小于0，路径无效
        continue;
      }
      level++;
    }
    return true; // 如果遍历完所有部分，路径有效
  }
//获取文件扩展名对应的MIME类型
//如果没有找到则返回application/octet-stream
  static std::string ExtMine(const std::string& filename) {
    size_t pos=filename.find_last_of('.'); // 查找最后一个点的位置
    if(pos==std::string::npos) return "application/octet-stream"; // 如果没有点


    std::string ext=filename.substr(pos); // 获取扩展名
    auto it = _mime_msg.find(ext); // 在_mime_msg中查找扩展名
    if(it == _mime_msg.end()) {
       return "application/octet-stream";
  }
  return it->second; // 如果找到，返回对应的MIME类型
  }


};

class HttpRequest {
 public:
std::string _method;// 请求方法
std::string _path;// 请求路径
std::string _version;// 请求版本
std::string _body;// 请求体
std::smatch _matches;// 正则匹配结果
std::unordered_map<std::string, std::string> _headers;// 请求头部
std::unordered_map<std::string, std::string> _query_params;// 查询字符串

public:
HttpRequest() :_version("HTTP/1.1") {}
void Reset() {
    _method.clear();
    _path.clear();
    _version = "HTTP/1.1";
    _body.clear();
    _headers.clear();
    _query_params.clear();
    std::smatch match;
    _matches = match;
}
void SetHeader(const std::string& key, const std::string& value) {
    _headers.insert(std::make_pair(key, value));
}
//判断是否有指定的头部字段
bool HasHeader(const std::string& key) const {
    auto it = _headers.find(key);
    if(it==_headers.end()) {
        return false; // 如果没有找到指定的头部，返回false
    }
    return true; // 如果找到了，返回true
  }
//获取指定头部字段的值
std::string GetHeader(const std::string& key) const {
    auto it = _headers.find(key);
    if(it != _headers.end()) {
        return it->second; // 如果找到了，返回对应的值
    }
    return ""; // 如果没有找到，返回空字符串
  }
//插入查询字符串
  void SetParam(const std::string& key, const std::string& value) {
    _query_params.insert(std::make_pair(key, value));
  }

  bool HasParam(const std::string& key) const {
    auto it = _query_params.find(key);
    if(it == _query_params.end()) {
        return false; // 如果没有找到指定的查询参数，返回false
    }
    return true; // 如果找到了，返回true
  }

  std::string GetParam(const std::string& key) const {
    auto it = _query_params.find(key);
    if(it != _query_params.end()) {
        return it->second; // 如果找到了，返回对应的值
    }
    return ""; // 如果没有找到，返回空字符串
  }

  size_t ContentLength() const {
    bool ret= HasHeader("Content-Length");//判断是否有Content-Length头部
    if(ret==false) {
      return 0; // 如果没有Content-Length头部，返回0
  }
  std::string content_length = GetHeader("Content-Length");//把头部的key拿过去把value取出来
  return std::stol(content_length); // 将Content-Length头部的string值转换为整数并返回
  }
//判断是否是短链接
  bool Close()const {
    if(HasHeader("Connection")==true&&GetHeader("Connection")=="keep-alive") {
      return false; // 如果有Connection头部且值为close，返回true
    }
    return true;
  }

};


class HttpResponse {
 public:
 int _status;// 响应状态码
bool _redirect_flag;// 是否重定向
std::string _body;// 响应体
std::string _redirect_url;// 重定向URL
std::unordered_map<std::string, std::string> _headers;// 响应头部

public:
HttpResponse() : _status(200), _redirect_flag(false) {}// 响应状态码默认为200--OK
HttpResponse(int status) : _status(status), _redirect_flag(false) {}// 响应状态码默认为200--OK

void Reset() {
    _status = 200; // 重置状态码为200
    _redirect_flag = false; // 重置重定向标志为false
    _body.clear(); // 清空响应体
    _redirect_url.clear(); // 清空重定向URL
    _headers.clear(); // 清空响应头部

  }

  void SetHeader(const std::string& key, const std::string& value) {
    _headers.insert(std::make_pair(key, value)); // 插入头部字段
  }

  //判断是否有指定的头部字段
bool HasHeader(const std::string& key) const {
    auto it = _headers.find(key);
    if(it==_headers.end()) {
        return false; // 如果没有找到指定的头部，返回false
    }
    return true; // 如果找到了，返回true
  }

  std::string GetHeader(const std::string& key) const {
    auto it = _headers.find(key);
    if(it != _headers.end()) {
        return it->second; // 如果找到了，返回对应的值
    }
    return ""; // 如果没有找到，返回空字符串
  }

void SetContext(const std::string& body,const std::string& type="text/html") {
    _body = body; // 设置响应体内容
    SetHeader("Content-Type", type); // 设置响应头部的Content-Type
  }

void SetRedirect(const std::string& url,int status = 302) {
    _redirect_flag = true; // 设置重定向标志为true
    _redirect_url = url; // 设置重定向URL
    _status = status; // 设置状态码为302--Found
 
  }

  //判断是否是短链接
  bool Close()const {
    if(HasHeader("Connection")==true&&GetHeader("Connection")=="keep-alive") {
      return false; // 如果有Connection头部且值为close，返回true
    }
    return true;
  }
};

typedef enum{
  RECV_HTTP_ERROR,
  RECV_HTTP_LINE,
  RECV_HTTP_HEAD,
  RECV_HTTP_BODY,
  RECV_HTTP_OVER
}HttpRecvStatu;

#define MAX_LINE 8192

class HttpContext{
private:
int _resp_statu;//响应状态码
HttpRecvStatu _recv_statu;//解析状态
HttpRequest _req;//请求信息

private:
bool ParseHttpLine(const std::string& line) {
std::smatch matches;
std::regex e("(GET|HEAD|POST|PUT|DELETE) ([^?]*)(?:\\?(.*))?(HTTP/1\\.[01])(?:\n|\r\n)?", std::regex::icase);//icase-忽略大小写
 bool ret = std::regex_match(line, matches, e);//line是请求行，matches是正则表达式匹配结果，e是正则表达式（匹配规则）

 if(ret==false)
 {
  _recv_statu=RECV_HTTP_ERROR; // 如果匹配失败，设置状态为错误
  _resp_statu=400; // 设置响应状态码为400--Bad Request
  return false; // 返回false表示解析失败
 }

 //1 : GET
 //2 : /bitejiuyeke/login
 //3 : user=xiaoming&pass=123123
 //4 : HTTP/1.1
 //请求⽅法的获取

 _req._method = matches[1].str(); // 获取请求方法
 std::transform(_req._method.begin(), _req._method.end(),_req._method.begin(), ::toupper);// 转换为大写
_req._path = Util::UrlDecode(matches[2].str(),false); // 获取请求路径
 _req._version = matches[4].str(); // 获取HTTP版本

std::vector<std::string> query_string_arry;//存放url分割完的部分
std::string query_string =matches[3].str();
Util::Split(query_string, "&", &query_string_arry);//分割查询字符串 key=val&key=val...
for(auto&it:query_string_arry)
{
  size_t pos= it.find("=");//查找等号位置
  if(pos==std::string::npos) {
   _recv_statu=RECV_HTTP_ERROR; // 如果没有找到等号，设置状态为错误
   _resp_statu=400; // 设置响应状态码为400--Bad Request
   return false; // 返回false表示解析失败
}
std::string key=Util::UrlDecode(it.substr(0,pos),true);//获取key
std::string value=Util::UrlDecode(it.substr(pos+1),true);//获取value
_req.SetParam(key, value); // 设置查询参数
}

return true; // 返回true表示解析成功

}

bool RecvHttpLine(Buffer*buf)//
{
  if(_recv_statu!=RECV_HTTP_LINE) {
    return false; // 如果当前状态不是接收HTTP行，返回false
  }
  std::string line=buf->Getlineandpop();
  if(line.empty()) {
    // 读取头部读不出数据时
    //1.Buffer缓冲区的可读数据大于MAX_LINE
    if(buf->Readablesize()>MAX_LINE) {
      _recv_statu=RECV_HTTP_ERROR; // 如果可读数据大于MAX_LINE，设置状态为错误
      _resp_statu=414; // 设置响应状态码为414--URI Too Long
      return false;
    }
    //2.Buffer缓冲区的可读数据为0--等待新的数据到来
    return true; 
  }

  if(line.size()>MAX_LINE) {
    _recv_statu=RECV_HTTP_ERROR; // 如果行长度大于MAX_LINE，设置状态为错误
    _resp_statu=414; // 设置响应状态码为414--URI Too Long
    return false;
  } 

  bool ret= ParseHttpLine(line);//解析HTTP行
 if(ret==false) return false; // 如果解析失败，返回false
  
  _recv_statu=RECV_HTTP_HEAD; // 解析成功，更新状态为接收HTTP头部
  return true;
}

bool RecvHttpHead(Buffer*buf) {
  if(_recv_statu!=RECV_HTTP_HEAD) {
    return false; // 如果当前状态不是接收HTTP头部，返回false
  }
  while(true) {
    std::string line=buf->Getlineandpop();//获取一行数据
    if(line.empty()) {
      // 读取头部读不出数据时
      //1.Buffer缓冲区的可读数据大于MAX_LINE
      if(buf->Readablesize()>MAX_LINE) {
        _recv_statu=RECV_HTTP_ERROR; // 如果可读数据大于MAX_LINE，设置状态为错误
        _resp_statu=400; // 设置响应状态码为400--Bad Request
        return false;
      }
      //2.Buffer缓冲区的可读数据为0--继续等待新的数据到来
      return true;
    }
    if(line.size()>MAX_LINE) {
      _recv_statu=RECV_HTTP_ERROR; // 如果行长度大于MAX_LINE，设置状态为错误
      _resp_statu=400; // 设置响应状态码为400--Bad Request
      return false;
    }
    if(line=="\r\n"||line=="\n") {
      _recv_statu=RECV_HTTP_BODY; // 如果遇到空行，表示头部结束，更新状态为接收HTTP体
       break;
    }
 bool ret=ParseHttpHead(line);//解析头部
 if(ret==false) return false; // 如果解析失败，返回false
 _recv_statu=RECV_HTTP_HEAD; // 解析成功，继续接收HTTP头部
 return true;
  }
  }


bool  ParseHttpHead(string& line)
{
  //key: value\r\nkey: value\r\n...
  if(line.empty()) return false;
  if(line.back()=='\n') {
    line.pop_back(); // 去掉末尾的换行符
  } 
  if(line.back()=='\r') {
    line.pop_back(); // 去掉末尾的回车符
  }
  size_t pos=line.find(": ");//查找冒号位置
  if(pos==std::string::npos) {
    _recv_statu=RECV_HTTP_ERROR; // 如果没有找到冒号，设置状态为错误
    _resp_statu=400; // 设置响应状态码为400-- Bad Request
    return false; // 返回false表示解析失败  
  }
  std::string key=line.substr(0,pos);//获取key
  std::string value=line.substr(pos+2);//获取value
  if(key.empty()||value.empty()) {
    _recv_statu=RECV_HTTP_ERROR; // 如果key或value为空，设置状态为错误
    _resp_statu=400; // 设置响应状态码为400-- Bad Request
    return false; // 返回false表示解析失败  
  }
  _req.SetHeader(key, value); // 设置请求头部
  return true; // 返回true表示解析成功
}

bool RecvHttpBody(Buffer*buf) {
  if(_recv_statu!=RECV_HTTP_BODY) {
    return false; // 如果当前状态不是接收HTTP体，返回false
  }
  if(_req.ContentLength()==0) {
    _recv_statu=RECV_HTTP_OVER; // 如果没有内容长度，表示HTTP体为空，更新状态为接收完成
    return true;
  }
 size_t reallen=_req.ContentLength()-_req._body.size();//获取内容长度--实际还需要接收的内容长度
if(buf->Readablesize()>=reallen)
{
_req._body.append(buf->RPosition(), reallen); // 如果缓冲区可读数据大于等于需要接收的内容长度，直接读取并追加到请求体
 
buf->MoveReadOffset(reallen); // 移动读取偏移量
_recv_statu=RECV_HTTP_OVER; // 更新状态为接收完成
 return true;
}
//缓冲区可读数据小于需要接收的内容长度
_req._body.append(buf->RPosition(), buf->Readablesize()); // 读取缓冲区所有可读数据并追加到请求体
buf->MoveReadOffset(buf->Readablesize()); // 移动读取偏移量
return true; // 继续等待新的数据到来
}

public:
HttpContext() : _resp_statu(200), _recv_statu(RECV_HTTP_LINE) {} // 初始化响应状态码为200，接收状态为接收HTTP行
void Reset() {
    _resp_statu = 200; // 重置响应状态码为200
    _recv_statu = RECV_HTTP_LINE; // 重置接收状态为接收HTTP行
    _req.Reset(); // 重置请求信息
  }
int Respstatu(){return _resp_statu;}//获取响应状态码
HttpRecvStatu RecvStatu(){return _recv_statu;}//获取接收
HttpRequest& Req(){return _req;}//获取请求信息

void RecvHttpRequest(Buffer*buf) {
    switch(_recv_statu){
      case RECV_HTTP_LINE:
        RecvHttpLine(buf); // 解析HTTP行
      case RECV_HTTP_HEAD:
        RecvHttpHead(buf); // 解析HTTP头部
      case RECV_HTTP_BODY:
        RecvHttpBody(buf); // 解析HTTP体
    } 
    return ;
  }
};

class HttpServer{

  private:
  using Handler=std::function<void(const PtrConnection&, HttpContext*)>;// 定义处理函数类型
  using Handlers=std::unordered_map<std::regex, Handler>;// 不同的正则表达式对应不同的处理函数

  Handlers _get_routes;// GET请求路由
  Handlers _post_routes;// POST请求路由
  Handlers _put_routes;// PUT请求路由
  Handlers _delete_routes;// DELETE请求路由

  std::string _wwwroot;// 静态文件根目录
  Tcpserver _server;// TCP服务器

  private:

  //处理错误请求
  void ErrorHandler(const HttpRequest&req,HttpResponse*rsp) {
   //1.组织一个错误展示页面
   std::string body;
   body+="<html>";
   body+="<head>";
   body+="<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">";
   body+="</head>";
   body+="<body>";
   body+="<h1>";
   body += std::to_string(rsp->_status);
 body += " ";
 body += Util::StatuDesc(rsp->_status);//状态码数字对应的描述
 body += "</h1>";
 body += "</body>";
 body += "</html>";
 rsp->SetContext(body, "text/html");//设置响应体内容和类型
  }

  //判断是否是静态资源请求
  bool IsFileHandler(const HttpRequest&req) {
   //1.必须设置静态资源目录
   if(_wwwroot.empty()) {
     return false; // 如果静态资源目录为空，返回false
   }
   //2.请求方法必须是GET或HEAD
   if(req._method!="GET"&&req._method!="HEAD") {
     return false; // 如果请求方法不是GET或HEAD，返回false
  }
  //3.请求路径必须是合法路径
  if(Util::ValidPath(req._path)==false) {
    return false; // 如果请求路径不合法，返回false
  }
  //4.请求路径必须存在且是一个普通文件，若是根目录/则默认追加 "index.html"
  std::string req_path = _wwwroot + req._path; // 拼接请求
  if(req_path.back() == '/') {
    req_path += "index.html"; // 如果请求路径以斜杠结尾，默认访问index.html
  }
  if(Util::IsFile(req_path)==false)//判断是否是一个普通文件
  {
    return false;
  }
return true;
}

//处理静态资源
  void FileHandler(const HttpRequest&req,HttpResponse*rsp)
  {
    std::string req_path=_wwwroot+req._path;// 拼接请求路径和静态文件根目录
    if(req_path.back()=='/') {
      req_path+="index.html"; // 如果请求路径以斜杠结尾，默认访问index.html
    }
    bool ret=Util::ReadFile(req_path, &rsp->_body);// 读取静态文件内容
    if(ret==false) {
      return;}
      std::string mime=Util::ExtMine(req_path);// 获取文件的MIME类型
      rsp->SetHeader("Content-Type", mime);// 设置响应头部的Content-Type
      return;
  }

  void Dispatcher(const HttpRequest&req,HttpResponse*rsp)
  {
    
  }


//缓冲区处理
  void OnMessage(const PtrConnection& conn, Buffer* buf) {
    while(buf->Readablesize()>0) {
      //1.获取上下文--conn对象的GetContext函数返回的是Any类型的指针，然后该指针调用get<HttpContext>函数返回HttpContext类型的指针
     HttpContext*context=conn->GetContext()->get<HttpContext>();//获取连接对应的HTTP上下文
     //2
     context->RecvHttpRequest(buf);//接收HTTP请求
     //3.判断解析状态
     HttpRequest &req=context->Req();//获取请求信息
     HttpResponse rsp(context->Respstatu());//用响应状态码初始化响应信息
     if(context->RecvStatu()>=400) {//如果解析状态大于等于400，表示解析错误
       ErrorHandler(req,&rsp);//调用错误处理函数
       WriteRespone(conn,req,&rsp);//写回错误信息响应给客户端
       context->Reset();//重置HTTP上下文
       buf->MoveReadOffset(buf->Readablesize());//清空缓冲区
       conn->Shutdown();//关闭连接
       return;

     }
     if(context->RecvStatu()!=RECV_HTTP_OVER) {
       return; // 如果解析状态不是接收完成，继续等待新的数据到来
     }
     //到这里说明解析完成
     //4.路由分发
     Route(req,&rsp);
      //5.写回响应信息
      WriteRespone(conn,req,&rsp);//写回处理信息响应给客户端
      //6.重置HTTP上下文，准备处理下一个请求
      context->Reset();
      if(rsp.Close()) conn->Shutdown();//如果是短连接，关闭连接
  
  }
  return ;
}

void Route(const HttpRequest&req,HttpResponse*rsp){
  //1.对请求进行分辨，看是静态资源请求还是功能性请求
  //
  if()
}
  void ErrorHandler(const HttpRequest&req,HttpResponse*rsp)
  {

  }
  void WriteRespone(const PtrConnection& conn,const HttpRequest&req,HttpResponse*rsp)
  {
  }
  


};



